/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package clientesocket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Leo
 */

/*
 * clase que se encarga de recibir o descargar los archivos del servidor
 */
public class Descarga implements Runnable {

    private Socket cliente;
    private DataInputStream entrada;
    private DataOutputStream salida;
    private FileOutputStream archivo;
    private String nombreArchivo;
    private VentanaCliente ventanita;
    private String ruta;
    private long tamano;
    private int posicion;
    private long cantidadDescargada;
    private int reconectar;
    private String ip;

    public Descarga(String nombreArchivo, VentanaCliente ventanita, int posicion, long cantidadDescargada, String ip, int reconectar) {
        this.nombreArchivo = nombreArchivo;
        this.ventanita = ventanita;
        this.posicion = posicion;
        this.cantidadDescargada = cantidadDescargada;
        this.ip = ip;
        this.reconectar = reconectar;
    }
    /*
     * metodo que se encargar de recibir o descargar archivos del servidor desde cero
     */
    public void descargarArchivo() {
        try {
            salida.writeUTF("DESCARGA");
            salida.writeUTF(nombreArchivo.replace("Copia_de_", ""));
            salida.writeUTF(ventanita.getUsuario());
            boolean existe = entrada.readBoolean();
            if (existe) {
                tamano = entrada.readLong();
                File f = new File(ruta + nombreArchivo);
                archivo = new FileOutputStream(f);
                byte[] buffer = new byte[1024];
                int len;
                ventanita.agregarfila(nombreArchivo, Long.valueOf(0), tamano, "Descargando", ruta);
                while ((len = entrada.read(buffer)) > 0) {
                    ventanita.actualizarcantidad(f.length(), posicion, "d");
                    archivo.write(buffer, 0, len);
                    ventanita.actualizarcantidad(f.length(), posicion, "d");
                }
                ventanita.actualizarcantidad(f.length(), posicion, "d");
                archivo.flush();
                archivo.close();
                this.cliente.close();
            } else {
                ventanita.alertaarchivoincompleto();
                reconectar(reconectar + 1);
            }
        } catch (Exception e) {
            System.out.println("se cayo en la descarga");
            ventanita.actualizarestado("Pausada la Descarga", posicion);
            reconectar(reconectar + 1);
        }
    }
    /*
     * metodo que se encarga de recibir o descargar archivos del servidor
     * que ya esten comenzados
     */
    public void continuarDescargarArchivo() {
        try {
            salida.writeUTF("CONTINUAR DESCARGA");
            salida.writeUTF(nombreArchivo.replace("Copia_de_", ""));
            salida.writeUTF(ventanita.getUsuario());
            boolean existe = entrada.readBoolean();
            if (existe) {
                File f = new File(ruta + nombreArchivo);
                archivo = new FileOutputStream(f, true);
                salida.writeLong(f.length());
                byte[] buffer = new byte[1024];
                int len;
                ventanita.actualizarestado("Descargando", posicion);
                while ((len = entrada.read(buffer)) > 0) {
                    ventanita.actualizarcantidad(f.length(), posicion, "d");
                    archivo.write(buffer, 0, len);
                    ventanita.actualizarcantidad(f.length(), posicion, "d");
                }
                ventanita.actualizarcantidad(f.length(), posicion, "d");
                archivo.flush();
                archivo.close();
                this.cliente.close();
            } else {
                ventanita.alertaarchivoincompleto();
                reconectar(reconectar + 1);
            }
        } catch (Exception e) {
            System.out.println("se cayo en continuar la descarga");
            ventanita.actualizarestado("Pausada la Descarga", posicion);
            reconectar(reconectar + 1);
        }
    }
    /*
     * metodo que se encarga de reconectar por si un servidor esta caido para la descarga
     */
    public void reconectar(int intento) {
        //esto es pa obtener el verdadero tamaño del archivo
        //luego de haber entrado en este hilo
        long cantidadDescargada2 = 0;
        String consola = "DESCARGA: ";
        File f = new File(ruta + nombreArchivo);
        if (f.exists()) {
            cantidadDescargada2 = f.length();
            consola = "CONTINUAR DESCARGA: ";
        }

        boolean tratar = true;
        String ipNuevo = null;
        switch (intento) {
            case 1:
                ipNuevo = VentanaLogin.configuracion.getIp();
                System.out.println(consola + "Reconectando con servidor 1: " + ipNuevo + " / Archivo " + nombreArchivo);
                break;
            case 2:
                ipNuevo = VentanaLogin.configuracion.getIp2();
                System.out.println(consola + "Reconectando con servidor 2: " + ipNuevo + " / Archivo " + nombreArchivo);
                break;
            case 3:
                ipNuevo = VentanaLogin.configuracion.getIp3();
                System.out.println(consola + "Reconectando con servidor 3: " + ipNuevo + " / Archivo " + nombreArchivo);
                break;
            default: {
                tratar = false;
                System.out.println(consola + "Ninguno de los servidores esta activo");
                ventanita.activarDescarga();
                ventanita.alertaerror();
            }
        }

        if (tratar) {
            if (cantidadDescargada2 != 0) {
                ventanita.actualizarestado("Pausada la Descarga", posicion);
                ventanita.getXml().escribirArchivos(ventanita);
            }

            Descarga hiloDescarga = new Descarga(nombreArchivo, ventanita, posicion, cantidadDescargada2, ipNuevo, intento);
            Thread thread = new Thread(hiloDescarga);
            thread.start();
        }
    }
    /*
     * metodo que se encarga de dar inicio al hilo
     */
    public void run() {
        try {
            ruta = ventanita.getRuta();
            cliente = new Socket(ip, Integer.parseInt(VentanaLogin.configuracion.getPuertoLogin()));
            entrada = new DataInputStream(this.cliente.getInputStream());
            salida = new DataOutputStream(this.cliente.getOutputStream());

            if (cantidadDescargada == 0) {
                descargarArchivo();
            } else {
                continuarDescargarArchivo();
            }

        } catch (UnknownHostException ex) {
            System.out.println("Intenta reconectar. Descarga");
            reconectar(reconectar + 1);

        } catch (IOException ex) {
            System.out.println("Intenta reconectar.. Descarga");
            reconectar(reconectar + 1);
        }
    }
}
